package com.lyf.scm.admin.domain.util;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.lyf.scm.admin.api.dto.RequirementConfirmationDTO;
import com.lyf.scm.admin.domain.excel.dto.RequirementDTO;
import com.lyf.scm.common.enums.RequirementPlanTargetEnum;
import com.lyf.scm.common.enums.ResponseMsg;
import com.rome.arch.core.exception.RomeException;
import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;
import java.util.*;

/**
 * 需求计划导入监听器
 *
 * @author wangchlei
 * @date 2020/11/08
 */
public class RequirementDataListener extends AnalysisEventListener<RequirementDTO> {
    private static final int[] DATE_TITLE_INDEXS = new int[]{7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20};
    private static String DELIMITER = "/";
    private Map<Integer, Date> avaliableDateRange;
    public List<RequirementConfirmationDTO> requirementConfirmationDTOs = new ArrayList<>();

    @Override
    public void invoke(RequirementDTO data, AnalysisContext context) {
        if (avaliableDateRange.size() == 0) {
            return;
        }
        if (!RequirementPlanTargetEnum.SUPPLY_CHAIN_CONFIRMATION_QTY.getDesc().equals(data.getGmvTarget())) {
            return;
        }
        String warehouse;
        String sku;
        String wareHouseStr = data.getWarehouse();
        if (StringUtils.isNotEmpty(wareHouseStr)) {
            String[] wareHouseInfo = wareHouseStr.split(DELIMITER);
            if (wareHouseInfo.length < 2) {
                throw new RomeException(ResponseMsg.EXCEPTION.getCode(), "第" + (context.readRowHolder().getRowIndex() + 1) + "行仓库编码不能为空");
            }
            warehouse = wareHouseInfo[1];
        } else {
            throw new RomeException(ResponseMsg.EXCEPTION.getCode(), "第" + (context.readRowHolder().getRowIndex() + 1) + "行仓库编码不能为空");
        }
        String skuStr = data.getSku();
        if (StringUtils.isNotEmpty(skuStr)) {
            String[] skuInfo = skuStr.split(DELIMITER);
            if (skuInfo.length < 2) {
                throw new RomeException(ResponseMsg.EXCEPTION.getCode(), "第" + (context.readRowHolder().getRowIndex() + 1) + "行sku编码不能为空");
            }
            sku = skuInfo[1];
        } else {
            throw new RomeException(ResponseMsg.EXCEPTION.getCode(), "第" + (context.readRowHolder().getRowIndex() + 1) + "行sku编码不能为空");
        }
        //日期
        Integer index;
        RequirementConfirmationDTO requirementConfirmationDTO;
        for (Map.Entry<Integer, Date> item : avaliableDateRange.entrySet()) {
            requirementConfirmationDTO = new RequirementConfirmationDTO();
            requirementConfirmationDTO.setSkuCode(sku);
            requirementConfirmationDTO.setWarehouseCode(warehouse);
            requirementConfirmationDTO.setPlanStartDate(item.getValue());
            index = item.getKey();
            switch (index) {
                case 7:
                    requirementConfirmationDTO.setSupplyChainConfirmationQty((data.getWeek1() == null || "".equals(data.getWeek1()) || "-".equals(data.getWeek1())) ? BigDecimal.ZERO : new BigDecimal(data.getWeek1()));
                    break;
                case 8:
                    requirementConfirmationDTO.setSupplyChainConfirmationQty((data.getWeek2() == null || "".equals(data.getWeek2()) || "-".equals(data.getWeek2())) ? BigDecimal.ZERO : new BigDecimal(data.getWeek2()));
                    break;
                case 9:
                    requirementConfirmationDTO.setSupplyChainConfirmationQty((data.getWeek3() == null || "".equals(data.getWeek3()) || "-".equals(data.getWeek3())) ? BigDecimal.ZERO : new BigDecimal(data.getWeek3()));
                    break;
                case 10:
                    requirementConfirmationDTO.setSupplyChainConfirmationQty((data.getWeek4() == null || "".equals(data.getWeek4()) || "-".equals(data.getWeek4())) ? BigDecimal.ZERO : new BigDecimal(data.getWeek4()));
                    break;
                case 11:
                    requirementConfirmationDTO.setSupplyChainConfirmationQty((data.getWeek5() == null || "".equals(data.getWeek5()) || "-".equals(data.getWeek5())) ? BigDecimal.ZERO : new BigDecimal(data.getWeek5()));
                    break;
                case 12:
                    requirementConfirmationDTO.setSupplyChainConfirmationQty((data.getWeek6() == null || "".equals(data.getWeek6()) || "-".equals(data.getWeek6())) ? BigDecimal.ZERO : new BigDecimal(data.getWeek6()));
                    break;
                case 13:
                    requirementConfirmationDTO.setSupplyChainConfirmationQty((data.getWeek7() == null || "".equals(data.getWeek7()) || "-".equals(data.getWeek7())) ? BigDecimal.ZERO : new BigDecimal(data.getWeek7()));
                    break;
                case 14:
                    requirementConfirmationDTO.setSupplyChainConfirmationQty((data.getWeek8() == null || "".equals(data.getWeek8()) || "-".equals(data.getWeek8())) ? BigDecimal.ZERO : new BigDecimal(data.getWeek8()));
                    break;
                case 15:
                    requirementConfirmationDTO.setSupplyChainConfirmationQty((data.getWeek9() == null || "".equals(data.getWeek9()) || "-".equals(data.getWeek9())) ? BigDecimal.ZERO : new BigDecimal(data.getWeek9()));
                    break;
                case 16:
                    requirementConfirmationDTO.setSupplyChainConfirmationQty((data.getWeek10() == null || "".equals(data.getWeek10()) || "-".equals(data.getWeek10())) ? BigDecimal.ZERO : new BigDecimal(data.getWeek10()));
                    break;
                case 17:
                    requirementConfirmationDTO.setSupplyChainConfirmationQty((data.getWeek11() == null || "".equals(data.getWeek11()) || "-".equals(data.getWeek11())) ? BigDecimal.ZERO : new BigDecimal(data.getWeek11()));
                    break;
                case 18:
                    requirementConfirmationDTO.setSupplyChainConfirmationQty((data.getWeek12() == null || "".equals(data.getWeek12()) || "-".equals(data.getWeek12())) ? BigDecimal.ZERO : new BigDecimal(data.getWeek12()));
                    break;
                case 19:
                    requirementConfirmationDTO.setSupplyChainConfirmationQty((data.getWeek13() == null || "".equals(data.getWeek13()) || "-".equals(data.getWeek13())) ? BigDecimal.ZERO : new BigDecimal(data.getWeek13()));
                    break;
                case 20:
                    requirementConfirmationDTO.setSupplyChainConfirmationQty((data.getWeek14() == null || "".equals(data.getWeek14()) || "-".equals(data.getWeek14())) ? BigDecimal.ZERO : new BigDecimal(data.getWeek14()));
                    break;
                default:
            }
            requirementConfirmationDTOs.add(requirementConfirmationDTO);
        }

    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {

    }

    /**
     * 读取表头数据
     *
     * @param headMap
     * @param context
     * @return void
     **/
    @Override
    public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
        //解析日期范围，提取有效列数据
        Date date = new Date();
        Date startDate = DateUtil.beginOfWeek(date);
        String year = DateUtil.format(startDate, "yyyy.");
        Map<Integer, Date> map = new HashMap<>();
        Date previousDate = null;
        Date itemDate;
        for (int item : DATE_TITLE_INDEXS) {
            itemDate = DateUtil.parse(year + headMap.get(item).split("-")[0], "yyyy.MM.dd");
            if (previousDate == null) {
                previousDate = itemDate;
            }
            //如果当前时间小于前一个时间，将当前时间转换为下一年的时间
            if (itemDate.getTime() < previousDate.getTime()) {
                itemDate = DateUtil.offset(itemDate, DateField.YEAR, 1);
            }
            if (startDate.getTime() <= itemDate.getTime()) {
                map.put(item, itemDate);
            }
            previousDate = itemDate;
        }
        this.avaliableDateRange = map;
    }

    public List<RequirementConfirmationDTO> getRequirementConfirmationDTOs() {
        return requirementConfirmationDTOs;
    }
}
